package myJs.user.workflow.featureSelection.diagnoseAna

import cats.effect.SyncIO
import japgolly.scalajs.react.component.Scala.Unmounted
import myJs.Implicits._
import myJs.myPkg.jquery._
import myJs.myPkg.{ColumnOptions, TableOptions}
import myJs.tool.Tool
import myJs.tool.Tool._
import myJs.user.mission.plot._
import myJs.user.workflow._
import myJs.user.workflow.featureSelection.AllFSSoft.FSSoftT
import org.scalajs.dom.document
import org.scalajs.dom.ext.Ajax
import org.scalajs.macrotaskexecutor.MacrotaskExecutor.Implicits._
import scalatags.Text.all._
import shared.Pojo._
import shared.{SharedTool, VarTool}

import scala.collection.immutable.SeqMap
import scala.scalajs.js.Dynamic.{global => g}
import scala.scalajs.js.JSConverters._
import myJs.myPkg.reactHookForm._
import shared.pojo.WorkflowMission._
import com.softwaremill.quicklens._
import myJs.projectCps._
import myJs.user.FeatureSelectionTool
import myJs.user.workflowMission.featureSelectionResult.FeatureSelectionResult

/** Created by yz on 2/12/2020
  */
object DiagnoseAna extends FSSoftT with DiagnoseAnaSoftT {

  val tableId = "table"

  def refreshFileInfo(idStr: String) = {
    val url = g.jsRoutes.controllers.WorkflowController.getFsResultFileInfo().url.toString
    Ajax
      .get(
        url = s"${url.noCache}&missionId=${Tool.getMissionId}&idStr=${idStr}",
        headers = Map("Content-Type" -> "application/json")
      )
      .map { xhr =>
        val array = xhr.responseText.toJDJAn.toJArJDS
        val headerMap =
          SeqMap("fileName" -> messages("file"), "rowNum" -> messages("rowsInDataFile"), "intro" -> messages("note"))
        val columnNames = headerMap.keyList
        val columns = columnNames
          .map { columnName =>
            val fmt = columnName
            val title = headerMap.getOrElse(columnName, columnName)
            ColumnOptions.field(columnName).title(title).sortable(true)
          }
          .toJSArray
          .concat(FeatureSelectionResult.operateColumn)
        array.groupBy(_("kind")).foreach { case (kind, subArray) =>
          val options = TableOptions.data(subArray).columns(columns).pagination(false)
          $(s"#${kind} #${tableId}").bootstrapTable("destroy").bootstrapTable(options)
        }
      }
  }

  override def refreshResult(idStr: String): Unit = {
    super.refreshResult(idStr)
    Tool.initMiniColors
    val index = SharedTool.getId(idStr)
    Tool.getConfigJsonData(idStr).map { rs =>
      refreshFileInfo(idStr)
      FeatureSelectionTool.resultShow(idStr)
      val data = FeatureSelectionTool.getFsData(rs).diagnoseAna(index)
      val rfPrefix = if (data.runRf) {
        List("RF")
      } else {
        FeatureSelectionTool.hideTab($(".result.diagnoseAna"), List("rf"))
        List.empty
      }
      val gbPrefix = if (data.runGb) {
        List("GB")
      } else {
        FeatureSelectionTool.hideTab($(".result.diagnoseAna"), List("gb"))
        List.empty
      }
      val lrPrefix = if (data.runLr) {
        List("LR")
      } else {
        FeatureSelectionTool.hideTab($(".result.diagnoseAna"), List("lr"))
        List.empty
      }
      val svmPrefix = if (data.runSvm) {
        List("SVM")
      } else {
        FeatureSelectionTool.hideTab($(".result.diagnoseAna"), List("svm"))
        List.empty
      }
      val enPrefix = if (data.runEn) {
        List("EN")
      } else {
        FeatureSelectionTool.hideTab($(".result.diagnoseAna"), List("en"))
        List.empty
      }
      val prefixs = rfPrefix ::: gbPrefix ::: lrPrefix ::: svmPrefix ::: enPrefix
      prefixs.foreach { prefix =>
        rocPlot.Cp.Props(idStr,prefix).render.renderIntoDOM(document.querySelector(s"#${prefix.toLowerCase}Roc #root"))
        prPlot.Cp.Props(idStr,prefix).render.renderIntoDOM(document.querySelector(s"#${prefix.toLowerCase}Pr #root"))

        if (VarTool.cvPrefixs.contains(prefix)) {
          val prefixLower = prefix.toLowerCase
          if (data.hasCv) {
            RocCvTab.init(idStr, prefix = prefix)
            RocCvEachTab.init(idStr, prefix = prefix)
            FeatureSelectionTool.showTab(
              $(s".result.diagnoseAna #${prefixLower}"),
              List(s"${prefixLower}RocCv", s"${prefixLower}RocCvEach")
            )
          } else {
            FeatureSelectionTool.hideTab(
              $(s".result.diagnoseAna #${prefixLower}"),
              List(s"${prefixLower}RocCv", s"${prefixLower}RocCvEach")
            )
          }
        }
        FeatureSelectionTool.showTab($(".result.diagnoseAna"), List(prefix.toLowerCase))
      }
    }
  }

  override def appendData(
      fieldArray: UseFieldArrayRT,
      fsData: FsData,
      fsDataChange: FsData => SyncIO[Unit],
      nodeId: String,
      extraData: ExtraData
  ) = {
    SyncIO{} >> {
      val group = Tool.getGroupVs(extraData.groups).head
      val eachData = EachDiagnoseAnaData(nodeId = nodeId, group = group)
      val newFsData = fsData.modify(_.diagnoseAna).using(_ :+ eachData)
      fieldArray.append(eachData)
      fsDataChange(newFsData)
    }
  }

  override def fieldArray(useForm: UseFormRT): UseFieldArrayRT = ReactHookForm.useFieldArray(
    UseFieldArrayOptions(
      control = useForm.control,
      name = "diagnoseAna"
    )
  )

  override def cp(
      fieldArray: UseFieldArrayRT,
      fsData: FsData,
      fsDataChange: FsData => SyncIO[Unit],
      fsDataModifyF: (FsData => FsData) => SyncIO[Unit],
      showIdStr: String,
      extraData: ExtraData,
      extraDataChange: ExtraData => SyncIO[Unit]
  ) = {
    Cp.Props(
      fieldArray = fieldArray,
      fsData = fsData,
      fsDataChange = fsDataChange,
      fsDataModifyF = fsDataModifyF,
      showIdStr = showIdStr,
      extraData = extraData,
      extraDataChange = extraDataChange
    ).render
  }

  override def removeData(fsData: FsData, fsDataChange: FsData => SyncIO[Unit], curI: Int) = {
    SyncIO{} >> {
      val newData = fsData.modify(_.diagnoseAna).using(_.removed(curI))
      fsDataChange(newData)
    }
  }

}
